package com.geekchique.runningbuddy.controller;

import java.util.Date;
import java.util.TreeMap;

import android.content.ComponentName;
import android.content.Context;
import android.content.ServiceConnection;
import android.location.Location;
import android.os.DeadObjectException;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.TextSwitcher;
import android.widget.TextView;

import com.geekchique.runningbuddy.activity.Stopwatch;
import com.geekchique.runningbuddy.activity.stopwatch.StopwatchTools;
import com.geekchique.runningbuddy.model.Jog;
import com.geekchique.runningbuddy.provider.ActivityID;
import com.geekchique.runningbuddy.service.IRemoteServiceCallback;
import com.geekchique.runningbuddy.service.IRemoteStopClockService;
import com.geekchique.runningbuddy.util.DBHelperImpl;
import com.geekchique.runningbuddy.view.StopwatchView;
import com.geekchique.runningbuddy.view.TargetTimeView;

public class StopwatchControllerImpl implements IStopClockController{

	private StopwatchView stopwatchView;
	private TargetTimeView stopwatchTargetView;
	private Stopwatch stopwatchActivity;
    private DBHelperImpl dbHelper;
	protected IRemoteStopClockService messageService;
	private boolean targetIsSet = false;
	private String targetTime = "00:00:00.00";
	private boolean stopclockSerivceIsRunning = false;
	public long startTime = 0L;
	private long stopTime = 0L;


    public StopwatchControllerImpl(Stopwatch stopwatchActivity){
    	this.stopwatchActivity = stopwatchActivity;
    	dbHelper = new DBHelperImpl(stopwatchActivity.getContext());
    }


	public void createStopClockView(Context activity, TextSwitcher stopClockTextSwitcher, Button startButton) {
			stopwatchView = new StopwatchView(
				activity,
				this,
				stopClockTextSwitcher,
				startButton
			);

		stopwatchView.resetStopClock();

	}

	public void createwatchClockTargetView(Context context,
			CheckBox checkBox,
			TextView hours,
			TextView minutes,
			TextView seconds,
			TextView milliseconds,
			Button hoursUp,
			Button hoursDown,
			TextView hoursSep,
			Button minutesUp,
			Button minutesDown,
			TextView minutesSep,
			Button secsUp,
			Button secsDown,
			TextView secondsSep,
			Button millisecsUp,
			Button millisecsDown) {


			stopwatchTargetView = new TargetTimeView(
					context,
					checkBox,
					hours,
					minutes,
					seconds,
					milliseconds,
					hoursUp,
					hoursDown,
					hoursSep,
					minutesUp,
					minutesDown,
					minutesSep,
					secsUp,
					secsDown,
					secondsSep,
					millisecsUp,
					millisecsDown,
					this
			);

			stopwatchTargetView.hideSetTargetTime();
	}

	public String elapsedTime = "0";

    private IRemoteServiceCallback mCallback = new IRemoteServiceCallback.Stub() {
		public void updatedStopwatch(String time) throws DeadObjectException {
			elapsedTime = time;
			stopwatchServiceHandler.sendMessage(stopwatchServiceHandler.obtainMessage(ActivityID.UPDATESTOPCLOCK));

		}
    };

    private ServiceConnection messageConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder service) {
            messageService = IRemoteStopClockService.Stub.asInterface(service);

            try {
                messageService.registerStopClockUpdateListener(mCallback);
            } catch (DeadObjectException e) {
            }

        }

        public void onServiceDisconnected(ComponentName className) {
            messageService = null;
        }
    };


	protected Handler stopwatchServiceHandler = new Handler() {
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case ActivityID.UPDATESTOPCLOCK:
            	updateRunningStopClock();
            	break;
			}
			super.handleMessage(msg);
		}
	};

	public void start() {
		stopwatchActivity.startStopwatchService(messageConnection);
		stopclockSerivceIsRunning = true;
		stopwatchView.switchStopwatchButton(ActivityID.STOPWATCH_RUNNING);
	}

	public void stop() {
		this.stopTime = System.currentTimeMillis();
		if(stopclockSerivceIsRunning){
			stopwatchActivity.stopStopClockService(messageConnection);
        	if (messageService != null) {
                try {
                    messageService.unregisterStopClockUpdateListener(mCallback);
                } catch (DeadObjectException e) {
                }
            }
        	stopwatchView.switchStopwatchButton(ActivityID.STOPCLOCK_NOT_RUNNING);
        }
		stopclockSerivceIsRunning = false;

		saveJogLogEntry("jog" + new Date().getTime(), this.startTime, this.stopTime);
	}


	private void updateRunningStopClock() {
		if (targetIsSet() && isTargetTimeReached(elapsedTime)) {
			this.stopTime = System.currentTimeMillis();
			stop();
			stopwatchView.setStopClock(this.targetTime);
		} else {
			stopwatchView.setStopClock(elapsedTime);
		}
	}

	public boolean targetIsSet(){
		return this.targetIsSet;
	}

	public String getTargetTime(){
		return this.targetTime;
	}

	public void setTargetTime(String targetTime){
		this.targetTime = targetTime;
	}

	public void setTargetCentiSecs(Integer centiSecs) {
		this.targetTime = StopwatchTools.setCentiSecs(centiSecs, this.targetTime);
	}

	public void setTargetSecs(Integer secs) {
		this.targetTime = StopwatchTools.setSecs(secs, this.targetTime);
	}

	public void setTargetMins(Integer mins) {
		this.targetTime = StopwatchTools.setMins(mins, this.targetTime);
	}

	public void setTargetHours(Integer hours) {
		this.targetTime = StopwatchTools.setHours(hours, this.targetTime);
	}

	private boolean isTargetTimeReached(String elapsedTime) {
		int stopClock = StopwatchTools.compare(this.targetTime, elapsedTime);

		return stopClock == StopwatchTools.EQUAL || stopClock == StopwatchTools.GREATER_THAN;
	}

	protected void saveJogLogEntry(String name, long startTime, long stopTime) {

		TreeMap<Long, Location> locationsAndTimes = new TreeMap<Long, Location>();

		addJogTime(startTime, -4229920, 55846809, locationsAndTimes);
    	addJogTime(startTime, -4231200, 55846809, locationsAndTimes);
    	addJogTime(stopTime, -4236400, 55851200, locationsAndTimes);
    	addJogTime(stopTime, -4236800, 55851000, locationsAndTimes);


		dbHelper.addJogEntry(new Jog(name, name, locationsAndTimes));
	}

	private void addJogTime(long time, int longitude, int latitude, TreeMap<Long, Location> listOfJogTimes) {
		Location pointLocation;
		pointLocation = new Location();
    	pointLocation.setLongitude(longitude);
    	pointLocation.setLatitude(latitude);
    	listOfJogTimes.put(time, pointLocation);
	}


	public void turnOffASetTargetTime() {
		this.targetIsSet = false;
	}


	public void turnOnASetTargetTime() {
		this.targetIsSet = true;
	}


	public void setStartTime(long currentTimeMillis) {
		this.startTime = currentTimeMillis;
	}


}
